package com.aier.entrance.icsocket;


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;

import com.aier.common.common.Constant;

public class TestMessageDecoder implements MessageDecoder{
    private String result;
    private String com;                                            //传回的命令方式
    private String[] cardNoArray;                                //53命令中会传回的卡号数组
    private int cardNo;                                        //53命令中会传回的卡号
    private String recordTime;                                 // 刷卡时间
    private String type;                                            //53命令何总门状态事件
    private String isMore;                                        //是否还有更多记录
    private String curNum;                                        //当前的记录号
    private String sn;                                            //设备序列号
    public static Map<String,String> snMap = new HashMap<String,String>();
    private String mapContent;
    private String sessionID;
   
    public TestMessageDecoder(){
       
    }
    @Override
    public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
      
       
//           int re = in.remaining();
//           if((re > 1)){
//               return MessageDecoderResult.OK;
//           }else{
//               return MessageDecoderResult.NEED_DATA;
//           }
       
        return MessageDecoderResult.OK;
       
       
       //return MessageDecoderResult.NOT_OK;
    }
    //真正解析socket数据
    @Override
    public MessageDecoderResult decode(IoSession session, IoBuffer in,
            ProtocolDecoderOutput out) throws Exception {
        /*
        TestMessage tMsg = new TestMessage();
        tMsg.setVersion(in.get());
        tMsg.setProtocolType(in.getShort());
        int msgLen = in.getInt();
        //字符串解码格式
        Charset charset = Charset.forName("GBK");
        CharsetDecoder decoder = charset.newDecoder();
        String msgBody = in.getString(msgLen,decoder);
        tMsg.setMsgLen(msgLen);
        tMsg.setMsgBody(msgBody);
        out.write(tMsg);
        */
        TestMessage tMsg = new TestMessage();
        result = in.getHexDump();

        com = result.trim().substring(Constant.num_6, Constant.num_8);    
        tMsg.setCom(com);
        
        switch (Integer.parseInt(com)) {
            case Constant.num_53:{                                                                    //刷卡记录处理
                cardNoArray = result.substring(Constant.num_21, Constant.num_32).split(" ");
                cardNo = getNoFromHexString(cardNoArray);
                
                int year = Constant.num_2000 + Integer.parseInt(result.substring(Constant.num_48, Constant.num_50),Constant.num_16);
                recordTime= String.format("%02d%02d-%02d-%02d %02d:%02d:%02d", 
                        year/Constant.num_100,
                        year%Constant.num_100,
                        Integer.parseInt(result.substring(Constant.num_45, Constant.num_47),Constant.num_16),
                        Integer.parseInt(result.substring(Constant.num_42, Constant.num_44),Constant.num_16),
                        Integer.parseInt(result.substring(Constant.num_39, Constant.num_41),Constant.num_16),
                        Integer.parseInt(result.substring(Constant.num_36, Constant.num_38),Constant.num_16),
                        Integer.parseInt(result.substring(Constant.num_33, Constant.num_35),Constant.num_16));
                type = result.substring(Constant.num_51, Constant.num_53);
                isMore = result.substring(Constant.num_57, Constant.num_59);
                curNum = result.substring(Constant.num_60, Constant.num_62);
                tMsg.setRecordTime(recordTime);
                tMsg.setIsMore(isMore);
                tMsg.setCurNum(curNum);
                tMsg.setCardNo(cardNo+"");
                tMsg.setType(type);
                break;
            }
                
            case Constant.num_54:{                                                                    //报警记录处理
                isMore = result.substring(Constant.num_45, Constant.num_47);
                curNum = result.substring(Constant.num_48, Constant.num_50);
                tMsg.setIsMore(isMore);
                tMsg.setCurNum(curNum);
                break;
            }
            
            case Constant.num_56:{
                
                sn = result.substring(Constant.num_85,Constant.num_86) + result.substring(Constant.num_88,Constant.num_89) + 
                     result.substring(Constant.num_91,Constant.num_92) + result.substring(Constant.num_94,Constant.num_95) + 
                     result.substring(Constant.num_97,Constant.num_98) + result.substring(Constant.num_100,Constant.num_101);                    
                tMsg.setSn(sn);
                
                sessionID = session.getId() + "";
                mapContent = snMap.get(sessionID);
                //System.out.println(snMap.size()+"==========");
                if((null == mapContent) || ("".equals(mapContent))){ 
                    //遍历map,清除相同value的键值对
                    snMap = removeSameValueFromMap(snMap, sn);
                    snMap.put(sessionID, sn);
                }
                
                
                break;
                        
            }
            
    
            default:
                break;
        }
            
              
        out.write(tMsg);
        return MessageDecoderResult.OK;
    }

        
    @Override
    public void finishDecode(IoSession session, ProtocolDecoderOutput out)
        throws Exception {
    }
    
    
    
    /**
     * 
     * @param map    存放以 线程ID为key，设备号为content的键值对
     * @param sn    设备号    
     * @return        删除相同value的之前存放的键值对
     */    
    public Map<String,String> removeSameValueFromMap(Map<String,String> map,String sn){
        Set<String> set = map.keySet();
    
        //遍历map
        for (Iterator<String> iterator = set.iterator(); iterator.hasNext();) {
            String key = iterator.next();
            String value = map.get(key);
            if(value.equals(sn)) {map.remove(key);}
        }
        return map;
        
    }
    
    
    /**
     * 
     * @param a    经过加密的16进制
     * @return    卡号
     */
    public int getNoFromHexString(String[] a){
        int n;
        int m;
        int num;
        int[] no = new int[Constant.num_4];
        for (int i = a.length-1,j=0; i >= 0; i--,j++) {
            n = Integer.parseInt(a[i].substring(0, 1), Constant.num_16);
            m = Integer.parseInt(a[i].substring(1, 2), Constant.num_16);
            num = n*Constant.num_16 + m;
            if(num > Constant.num_127) {no[j] = num - Constant.num_256;}
            else {no[j] = num;}
        }
        
        byte[] b = new byte[]{(byte)no[0],(byte)no[1],(byte)no[2],(byte)no[Constant.num_3]};
        int value= 0;
        for (int i = 0; i < Constant.num_4; i++) {
            int shift= (Constant.num_4 - 1 - i) * Constant.num_8;
            value +=(b[i + 0] & Constant.num_000000ff) << shift;//往高位游
        }
        
        return value;
        
    }
    
}
